package strategy

import (
	"fmt"
	"strings"
	"super/constant"
	"super/db"
	"super/global"

	"github.com/duke-git/lancet/v2/slice"
	"github.com/nguyenthenguyen/docx"
)

type DdlDocStrategy struct {
}

func (DdlDocStrategy) Init() {
	if db.Dao == nil {
		if err := db.InitDB(); err != nil {
			fmt.Println(err)
			fmt.Print("super>")
			return
		}
	}
	global.CurStatus = constant.DdlDoc
	fmt.Print("ddlDoc>")
}

func (DdlDocStrategy) Handle(str string) {
	replaceDocx, err := docx.ReadDocxFile("./insert.docx")
	if err != nil {
		fmt.Println(err)
	}
	docx := replaceDocx.Editable()
	err = createDdlTableDoc(docx, str)
	if err != nil {
		fmt.Println(err)
	}
	err = createDdlIndexDoc(docx, str)
	if err != nil {
		fmt.Println(err)
	}

	err = docx.WriteToFile("./insertFinish.docx")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("create finished!")
	}
	replaceDocx.Close()
	fmt.Print("ddlDoc>")
}
func createDdlTableDoc(docx *docx.Docx, table string) error {
	var tableComment string
	err := db.Dao.Get(&tableComment, "SELECT table_comment FROM information_schema.TABLES WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", table, db.TableSchema)
	if err != nil {
		return err
	}
	rows, err := db.Dao.Query("select column_name, column_type, column_key, column_comment, is_nullable, column_default from information_schema.`COLUMNS` c where TABLE_NAME = ? AND TABLE_SCHEMA = ?", table, db.TableSchema)
	if err != nil {
		return err
	}

	docx.Replace("${dbname}", db.TableSchema, 1)
	docx.Replace("${table}", table, 1)
	docx.Replace("${tableDesc}", tableComment, 1)

	var column_name, column_type, column_key, column_comment, is_nullable, column_default string
	i := 0
	for rows.Next() {
		rows.Scan(&column_name, &column_type, &column_key, &column_comment, &is_nullable, &column_default)
		docxReplace(docx, i, "zdm", column_name)
		docxReplace(docx, i, "jd", column_type)
		docxReplace(docx, i, "sy", column_comment)

		id := "否"
		if column_key == "PRI" {
			id = "是"
		}
		docxReplace(docx, i, "id", id)
		docxReplace(docx, i, "wy", id)
		fk := "是"
		if is_nullable == "YES" {
			fk = "否"
		}
		docxReplace(docx, i, "fk", fk)
		docxReplace(docx, i, "zz", "否")
		docxReplace(docx, i, "mr", column_default)
		docxReplace(docx, i, "sm", column_comment)
		docxReplace(docx, i, "ywcj", "")
		i++
	}

	rows.Close()
	fmt.Println("create table successful!")

	return nil
}

func docxReplace(docx *docx.Docx, num int, name, val string) {
	err := docx.Replace(fmt.Sprintf("${%s%d}", name, num), val, 1)
	if err != nil {
		fmt.Println(err)
	}
}

func createDdlIndexDoc(docx *docx.Docx, table string) error {
	rows, err := db.Dao.Query("show index from " + table)
	if err != nil {
		return err
	}
	var tableComment string
	err = db.Dao.Get(&tableComment, "SELECT table_comment FROM information_schema.TABLES WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", table, db.TableSchema)
	if err != nil {
		return err
	}

	docx.Replace("${dbname1}", db.TableSchema, 1)
	docx.Replace("${table1}", table, 1)
	docx.Replace("${tableDesc1}", tableComment, 1)

	maps := db.Rows2Maps(rows)

	ms := slice.GroupWith(maps, func(m map[string]interface{}) string { return m["Key_name"].(string) })
	index := 0
	for k, m := range ms {
		idxName := k
		nonUnique := m[0]["Non_unique"].(string)
		fields := slice.Map(m, func(i int, item map[string]interface{}) string {
			return item["Column_name"].(string)
		})
		columns := strings.Join(fields, ",")

		docxReplace(docx, index, "idx_name", idxName)
		docxReplace(docx, index, "idx_fields", columns)
		var isId string
		if idxName == "PRIMARY" {
			isId = "是"
		}
		docxReplace(docx, index, "is_id", isId)
		var isUnique string
		if nonUnique == "0" {
			isUnique = "是"
		}
		docxReplace(docx, index, "idx_wy", isUnique)
		docxReplace(docx, index, "idx_ywcj", "")

		index++
	}
	fmt.Println("create index successful!")

	return nil
}
